import LocalStorageKey from '@/constant/LocalStorageKey'
import IResVO from '@/model/vo/common/IResVO'
import { AxiosRequestConfig, AxiosResponse } from 'axios'
import { ToastError } from '../CommonUtil'
import { logout } from '../UserUtil'

let hiddenErrorMsgFlag = false

// 请求拦截器
export const request = {
  onFulfilled(config: AxiosRequestConfig) {
    if (!config.url?.startsWith('http')) {
      // 不以 http开头的，才携带 jwt
      config.headers!['Authorization'] =
        localStorage.getItem(LocalStorageKey.JWT) || ''
      config.headers!['category'] = 1 // 类别：1 H5（网页） 2 APP（移动端） 3 PC（桌面程序）
    }

    if (config.headers?.hiddenErrorMsg) {
      hiddenErrorMsgFlag = true
    }

    return config
  },
  onRejected(err: any) {
    ToastError('请求错误：' + err.message + ' (灬ꈍ ꈍ灬)', 5)
    return Promise.reject(err)
  },
}

// 响应拦截器
export const response = {
  onFulfilled(response: AxiosResponse<IResVO>) {
    const config = response.config
    if (config.url?.startsWith('http')) {
      // 如果是 http请求，则直接返回 response
      return response
    }
    if (config.responseType === 'blob') {
      // 如果请求的是文件，则直接返回 response
      return response
    }

    const hiddenErrorMsg = config.headers?.hiddenErrorMsg

    // 接口请求报错，是否隐藏错误信息：关闭
    if (hiddenErrorMsg) {
      hiddenErrorMsgFlag = false
    }

    const res = response.data
    if (res.code !== 200 || !res.success) {
      if (res.code === 100111) {
        // 这是 后台未登录的错误代码，直接跳转到登录页面
        if (localStorage.getItem(LocalStorageKey.JWT)) {
          logout()
          ToastError(res.msg, 5)
        }
      } else {
        // 接口请求报错，是否隐藏错误信息：结束方法
        if (hiddenErrorMsg) {
          return Promise.reject(new Error(res.msg || 'Error')) // 这里会触发 catch
        }
        ToastError(res.msg, 5)
      }
      return Promise.reject(new Error(res.msg || 'Error')) // 这里会 触发 catch，意思是：只要 code 不等于 200 或者 res.success === false，都不会走 then，而去走 catch
    } else {
      return response
    }
  },
  onRejected(err: any) {
    if (hiddenErrorMsgFlag) {
      return Promise.reject(err) // 这里会触发 catch
    }

    // 所有的请求错误，例如 500 404 错误，只要不是 200，都会在这里
    let msg: string = err.message
    if (msg === 'Network Error') {
      msg = '连接异常，请重试 ٩(๑>◡<๑)۶'
    } else if (msg.includes('timeout')) {
      msg = timeoutMsg
    } else if (msg.includes('Request failed with status code')) {
      msg =
        '接口【' +
        msg.substring(msg.length - 3) +
        '】异常，请联系管理员 (๑´ㅂ`๑) '
    }

    ToastError(msg || '请求错误：' + err.message + ' (灬ꈍ ꈍ灬)', 5)

    return Promise.reject(err) // 这里会触发 catch
  },
}

export const timeoutMsg = '请求超时，请重试 ٩(๑❛ᴗ❛๑)۶'

export const maxTryNum = 10 // 接口错误重试最大次数
